﻿using System;
using System.Collections.Generic;
using System.Text;

namespace Cabal.Kernel.DataSet
{
    /// <summary>
    /// 模拟Linq系统
    /// </summary>
    public class CabalLinq
    {
        List<CLKeyValuePair> _expset = new List<CLKeyValuePair>();

        /// <summary>
        /// 添加键值对应的项目
        /// </summary>
        public void AddData(string exp)
        {
            string key, value;
            if (SplitExp(exp, out key, out value))
                AddData(key, value);
            else
                throw new CLExpExcpetion(exp);
        }
        public void AddData(string key, string value)
        {
            _expset.Add(new CLKeyValuePair(key, value));
        }

        /// <summary>
        /// 移除所有指定键的项目
        /// </summary>
        public void RemoveAll(string key)
        {
            for (int i = _expset.Count - 1; i >= 0; i--)
                if (_expset[i].Key == key)
                    _expset.RemoveAt(i);
        }
        /// <summary>
        /// 移除指定项目
        /// </summary>
        public void Remove(CLKeyValuePair pair)
        {
            Remove(pair.Key, pair.Value);
        }
        public void Remove(string exp)
        {
            string key, value;
            if (SplitExp(exp, out key, out value))
                Remove(key, value);
            else
                throw new CLExpExcpetion(exp);
        }
        public void Remove(string key, string value)
        {
            for (int i = _expset.Count - 1; i >= 0; i--)
                if (_expset[i].Key == key && _expset[i].Value == value)
                    _expset.RemoveAt(i);
        }

        /// <summary>
        /// 检视是否存在符合表达式的项目
        /// </summary>
        public bool Select(string exp)
        {
            string key, value;
            if (SplitExp(exp, out key, out value))
                return Select(key, value);
            else
                throw new CLExpExcpetion(exp);
        }
        public bool Select(string key, string value)
        {
            foreach (CLKeyValuePair i in _expset)
                if (i.Key == key && i.Value == value)
                    return true;
            return false;
        }

        /// <summary>
        /// 检查是否存在指定的键
        /// </summary>
        public bool Contans(string key)
        {
            foreach (CLKeyValuePair i in _expset)
                if (i.Key == key) return true;
            return false;
        }

        /// <summary>
        /// 设置值，若不存在键则添加，存在多个则覆盖只保留一个
        /// </summary>
        public void SetValue(string exp)
        {
            string key, value;
            if (SplitExp(exp, out key, out value))
                SetValue(key, value);
            else
                throw new CLExpExcpetion(exp);
        }
        public void SetValue(string key, string value)
        {
            RemoveAll(key);
            AddData(key, value);
        }

        /// <summary>
        /// 获取制定键的值(第一个)
        /// </summary>
        public string GetValue(string key)
        {
            foreach (CLKeyValuePair i in _expset)
                if (i.Key == key) return i.Value;
            return null;
        }
        /// <summary>
        /// 获取制定键的全部值列表
        /// </summary>
        public List<string> GetValues(string key)
        {
            List<string> list = new List<string>();
            foreach (CLKeyValuePair i in _expset)
                if (i.Key == key) list.Add(i.Value);
            return list;
        }
        public List<CLKeyValuePair> GetValuesPair(string key)
        {
            List<CLKeyValuePair> list = new List<CLKeyValuePair>();
            foreach (CLKeyValuePair i in _expset)
                if (i.Key == key) list.Add(i);
            return list;
        }

        internal static bool SplitExp(string exp, out string key, out string value)
        {
            key = null;
            value = null;

            int i = exp.IndexOf('=');
            if (i <= 0 || i == exp.Length - 1) return false;

            key = exp.Substring(0, i);
            value = exp.Substring(i + 1);
            return true;
        }
    }

    /// <summary>
    /// 表示一个键值对的结构，用于CabalLinq数据结构
    /// </summary>
    public struct CLKeyValuePair
    {
        public CLKeyValuePair(string key, string value)
        {
            Key = key;
            Value = value;
        }
        public string Key;
        public string Value;
    }

    /// <summary>
    /// CabalLinq表达式异常
    /// </summary>
    public class CLExpExcpetion : Exception
    {
        public CLExpExcpetion(string exp)
            : base("CabalLinq表达式错误") 
        {
            Exp = exp;
        }
        public string Exp;
    }
}
